package bjut.zrpc.core.optimization.factory;

import java.lang.reflect.InvocationTargetException;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @Author: zhuzhiming
 * @Date: 2022/6/23 19:19
 */
public final class SingletonFactory {

    private static final ConcurrentHashMap<String, Object> SINGLETON_INSTANCE_MAP = new ConcurrentHashMap<>();

    public static <T> T getInstance(Class<T> cls) {

        if (cls == null) throw new IllegalArgumentException("type  must no be null");

        String key = cls.toString();

        Object aClass = SINGLETON_INSTANCE_MAP.get(key);

        if (aClass == null) {
            synchronized (SingletonFactory.class) {
                aClass = SINGLETON_INSTANCE_MAP.get(key);
                if (aClass == null) {
                    aClass = SINGLETON_INSTANCE_MAP.computeIfAbsent(key, value -> {
                        try {
                            return cls.newInstance();
                        } catch (InstantiationException | IllegalAccessException  e) {
                            throw new ClassCastException("class cast exception");
                        }
                    });
                }
            }
        }
        return cls.cast(aClass);
    }

}
